package com.army.onlineedict.common;

import ohos.app.AbilityContext;
import ohos.data.DatabaseHelper;
import ohos.data.rdb.RdbOpenCallback;
import ohos.data.rdb.RdbStore;
import ohos.data.rdb.StoreConfig;
import ohos.data.resultset.ResultSet;
import ohos.global.resource.Resource;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

public class MyDict {
    private AbilityContext context;
    private File dictPath;
    private File dbPath;
    private RdbStore store;
    private StoreConfig config = StoreConfig.newDefaultConfig("dict.sqlite");
    private static final RdbOpenCallback callback = new RdbOpenCallback() {
        @Override
        public void onCreate(RdbStore rdbStore) {

        }

        @Override
        public void onUpgrade(RdbStore rdbStore, int i, int i1) {

        }
    };

    public MyDict(AbilityContext context) {
        this.context = context;
        dictPath = new File(context.getDataDir().toString() + "/MainAbility/databases/db");
        if (!dictPath.exists()) {
            dictPath.mkdirs();
        }
        dbPath = new File(Paths.get(dictPath.toString(), "dict.sqlite").toString());
    }

    private void extractDB() throws IOException {
        // 读取dict.sqlite文件的字节流
        Resource resource = context.getResourceManager().getRawFileEntry("resources/rawfile/dict.sqlite").openRawFile();
        if (dbPath.exists()) {
            dbPath.delete();
        }

        FileOutputStream fos = new FileOutputStream(dbPath);
        byte[] buffer = new byte[4096];
        int count = 0;
        while ((count = resource.read(buffer)) >= 0) {
            fos.write(buffer, 0, count);
        }
        resource.close();
        fos.close();
    }

    public void init() throws IOException {
        // 初始化数据库
        extractDB();
        // 打开数据库
        DatabaseHelper helper = new DatabaseHelper(context);
        // 获取数据库操作类
        store = helper.getRdbStore(config, 1, callback, null);
    }
    // 搜索本地词库
    public List<WordData> searchLocalDict(String word) {
        word = word.toLowerCase();
        String[] args = new String[]{word};
        ResultSet resultSet = store.querySql("select * from t_words where word=?", args);
        List<WordData> result = new ArrayList<>();
        while (resultSet.goToNextRow()) {
            WordData wordData = new WordData();
            wordData.type = resultSet.getString(2);
            wordData.meanings = resultSet.getString(3);
            result.add(wordData);
        }
        resultSet.close();

        return result;
    }

    // 异步搜索网络词典
    public void searchWebDict(String word, SearchWordCallback callback) {
        word = word.toLowerCase();
        // 异步搜索
        new AsyncSearchWord(word, store, callback).start();
    }

}

/**
 * 多线程异步查询单词
 */
class AsyncSearchWord extends Thread {
    private String word;
    private RdbStore store;
    private SearchWordCallback callback;

    public AsyncSearchWord(String word, RdbStore rdbStore, SearchWordCallback callback) {
        this.word = word;
        this.store = rdbStore;
        this.callback = callback;
    }

    @Override
    public void run() {
        try {
            // 获取搜索结果（HTML形式）
            Document doc = Jsoup.connect("https://www.iciba.com/word?w=" +  word).get();
            Elements ulElements = doc.getElementsByClass("Mean_part__1RA2V");
            String insertSQL = "insert into t_words(word, type, meanings) values (?, ?, ?);";
            List<WordData> wordDataList = new ArrayList<>();

            for (Element ulElement : ulElements) {
                Elements liElements = ulElement.getElementsByTag("li");
                for (Element liElement : liElements) {
                    WordData wordData = new WordData();
                    Elements iElements = liElement.getElementsByTag("i");
                    for (Element iElement : iElements) {
                        wordData.type = iElement.text();
                        break;
                    }

                    Elements divElements = liElement.getElementsByTag("div");
                    for (Element divElement : divElements) {
                        wordData.meanings = divElement.text();
                        break;
                    }

                    // 插入每一个词性的解释
                    wordDataList.add(wordData);
                    store.executeSql(insertSQL, new String[]{word, wordData.type, wordData.meanings});
                }

                break;
            }

            if (null != callback) {
                callback.onResult(wordDataList);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}